package edu.towson.cosc.cosc455.biedermann.compiler;

import edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer;

public class MySyntaxAnalyzer implements SyntaxAnalyzer {
	
	/**
	 * Method to match lolspeak structure
	 * checks for components in correct order
	 * @see edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#lolcode()
	 */
	@Override
	public void lolcode() {
		if(!MyCompiler.token.equalsIgnoreCase(LexicalTokens.DOC_BEGIN)){
			System.err.println("Syntax Error: "+ MyCompiler.token +" when " + LexicalTokens.DOC_BEGIN +" was expected.");
			System.exit(0);
		}

		MyCompiler.lexer.getNextToken();
		
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.COMMENT_BEGIN)){
			comment();
			MyCompiler.lexer.getNextToken();
		}
		
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.DEFINE_VAR_BEGIN)){
			define(); 
		}
		
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.HEAD_BEGIN)){
			head();
			MyCompiler.lexer.getNextToken();
		}
		
		body();
				
		if(!MyCompiler.token.equalsIgnoreCase(LexicalTokens.DOC_END)){
			System.err.println("Syntax Error: "+ MyCompiler.token +" when " + LexicalTokens.DOC_END +" was expected.");
			System.exit(0);
		}
		if(MyLexicalAnalyzer.currentPosition <= (MyCompiler.inputTxt.length() -1)){
			System.err.println("Syntax Error: Additional tokens or text found after file end");
			System.exit(0);
		}
		
	}

	/**
	 * Method that checks for remaining syntax of a comment
	 * @see edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#comment()
	 */
	@Override
	public void comment() {
		MyCompiler.lexer.getNextToken();

		if(!LexicalTokens.textList.contains(MyCompiler.token)){
			System.err.println("Syntax Error: Not valid text, tag found");
			System.exit(0);
		}
		
		MyCompiler.lexer.getNextToken();
		if (!MyCompiler.token.equalsIgnoreCase(LexicalTokens.COMMENT_END)){
			System.err.println("Syntax Error: "+ MyCompiler.token +" when " + LexicalTokens.COMMENT_END +" was expected.");
			System.exit(0);
		}

	}

	/**
	 * Method that checks for remaining syntax of a head 
	 * and looks for the beginning of title
	 * @see edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#head()
	 */
	@Override
	public void head() {
		MyCompiler.lexer.getNextToken();

		if (MyCompiler.token.equalsIgnoreCase(LexicalTokens.TITLE_BEGIN)){
			title();
		}
		MyCompiler.lexer.getNextToken();
		
		if (!MyCompiler.token.equalsIgnoreCase(LexicalTokens.HEAD_END)){
			System.err.println("Syntax Error: "+ MyCompiler.token +" when " + LexicalTokens.HEAD_END +" was expected.");
			System.exit(0);
		}

	}

	/**	
	 ** Method that checks for remaining syntax of a title
	 * @see edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#title()
	 */
	@Override
	public void title() {
		MyCompiler.lexer.getNextToken();

		if(!LexicalTokens.textList.contains(MyCompiler.token)){
			System.err.println("Syntax Error: Not valid text, tag found");
			System.exit(0);
		}
		
		MyCompiler.lexer.getNextToken();
		if (!MyCompiler.token.equalsIgnoreCase(LexicalTokens.TITLE_END)){
			System.err.println("Syntax Error: "+ MyCompiler.token +" when " + LexicalTokens.TITLE_END +" was expected.");
			System.exit(0);
		}
	}

	/**
	 * Method to check order and repetition of stylistic components 
	 * @see edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#body()
	 */
	public void body(){
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.COMMENT_BEGIN)){
			comment();
			MyCompiler.lexer.getNextToken();
			body();
		}
		
		innertext();
		
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.PARA_BEGIN)){
			paragraph();
			MyCompiler.lexer.getNextToken();
			body();
		}
		
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.BOLD_BEGIN)){
			bold();
			MyCompiler.lexer.getNextToken();
			body();
		}
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITALICS_BEGIN)){
			italics();
			MyCompiler.lexer.getNextToken();
			body();
		}
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.LIST_BEGIN)){
			list();
			MyCompiler.lexer.getNextToken();
			body();
		}
	}
	
	
	/**
	 * Method to start a new paragraph
	 * @see edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#paragraph()
	 */
	@Override
	public void paragraph() {
		MyCompiler.lexer.getNextToken();
		
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.DEFINE_VAR_BEGIN)){
			define(); 
		}
		
		innerpara();
		
		if (!MyCompiler.token.equalsIgnoreCase(LexicalTokens.PARA_END)){
			System.err.println("Syntax Error: "+ MyCompiler.token +" when " + LexicalTokens.COMMENT_END +" was expected.");
			System.exit(0);
		}
	}

	/**
	 * Method to keep order in paragraph
	 * @see edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#innerpara()
	 */
	public void innerpara(){
		innertext();
		
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.BOLD_BEGIN)){
			bold();
			MyCompiler.lexer.getNextToken();
			innerpara();
		}
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITALICS_BEGIN)){
			italics();
			MyCompiler.lexer.getNextToken();
			innerpara();
		}
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.LIST_BEGIN)){
			list();
			MyCompiler.lexer.getNextToken();
			innerpara();
		}
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.NEWLINE)){
			MyCompiler.lexer.getNextToken();
			innerpara();
			}
	}
	
	/**
	 * Method to have variable use and other components
	 * @see edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#innertext()
	 */
	public void innertext(){
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.VARIABLE_BEGIN)){
			use();
			MyCompiler.lexer.getNextToken();
			innertext();
			}
		
		if(LexicalTokens.textList.contains(MyCompiler.token)){
			MyCompiler.lexer.getNextToken();
			innertext();
			}
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.NEWLINE)){
			MyCompiler.lexer.getNextToken();
			innertext();
			}
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.SOUNDS_BEGIN)){
			audio();
			MyCompiler.lexer.getNextToken();
			innertext();
			}
		
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.VIDEO_BEGIN)){
			video();
			MyCompiler.lexer.getNextToken();
			innertext();
			}
		}
	/**
	 * Method that checks for remaining syntax of a bold
	 * @see edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#bold()
	 */
	@Override
	public void bold() {
		MyCompiler.lexer.getNextToken();
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.DEFINE_VAR_BEGIN)){
			define();
			//bold();
			//MyCompiler.lexer.getNextToken();
		}
		innertext();
		if (!MyCompiler.token.equalsIgnoreCase(LexicalTokens.BOLD_END)){
			System.err.println("Syntax Error: "+ MyCompiler.token +" when " + LexicalTokens.BOLD_END +" was expected.");
			System.exit(0);
		}
	}

	/**
	 * Method that checks for remaining syntax of a italics
	 * @see edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#italics()
	 */
	@Override
	public void italics() {
		MyCompiler.lexer.getNextToken();
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.DEFINE_VAR_BEGIN)){
			define();
		}
		
		innertext();
		if (!MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITALICS_END)){
			System.err.println("Syntax Error: "+ MyCompiler.token +" when " + LexicalTokens.ITALICS_END +" was expected.");
			System.exit(0);
		}
	}

	/**
	 * Method that checks for remaining syntax of a list
	 * @see edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#list()
	 */
	@Override
	public void list() {
		MyCompiler.lexer.getNextToken();
		if(!MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITEM_BEGIN)){
			System.err.println("SYNTAX ERROR: " 
					+ MyCompiler.token + " when " + LexicalTokens.ITEM_BEGIN + " was expected");
						System.exit(0);
		}
		item();
		if(!MyCompiler.token.equalsIgnoreCase(LexicalTokens.LIST_END)){
			System.err.println("SYNTAX ERROR: " 
					+ MyCompiler.token + " when " + LexicalTokens.LIST_END + " was expected");
						System.exit(0);
		}
	}

	/**
	 *Method that checks for remaining syntax of an item
	 * @see edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#item()
	 */
	@Override
	public void item() {
		MyCompiler.lexer.getNextToken();
		innerlist();
		if(!MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITEM_END)){
			System.err.println("SYNTAX ERROR: " 
					+ MyCompiler.token + " when " + LexicalTokens.ITEM_END + " was expected");
						System.exit(0);
		}
		MyCompiler.lexer.getNextToken();
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITEM_BEGIN)){
			item();
		}
		
	}
	
	/**
	 *Method that checks for remaining syntax of item components 
	 *@see edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#innerlist()
	 */
	public void innerlist(){
		innertext();
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.BOLD_BEGIN)){
			bold();
			MyCompiler.lexer.getNextToken();
			innerlist();
		}
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITALICS_BEGIN)){
			italics();
			MyCompiler.lexer.getNextToken();
			innerlist();
		}
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.BOLD_BEGIN)){
			bold();
			MyCompiler.lexer.getNextToken();
			innerlist();
		}
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.LIST_BEGIN)){
			list();
			MyCompiler.lexer.getNextToken();
			innerlist();
		}		
	}

	/**
	 *Method that checks for remaining syntax of an audio link
	 * @see edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#audio()
	 */
	@Override
	public void audio() {
		MyCompiler.lexer.getNextToken();

		if(!LexicalTokens.textList.contains(MyCompiler.token)){
			System.err.println("Syntax Error: Not valid text, tag found");
			System.exit(0);
		}
		
		MyCompiler.lexer.getNextToken();
		if (!MyCompiler.token.equalsIgnoreCase(LexicalTokens.SOUNDS_END)){
			System.err.println("Syntax Error: "+ MyCompiler.token +" when " + LexicalTokens.COMMENT_END +" was expected.");
			System.exit(0);
		}
	}

	/**
	 *Method that checks for remaining syntax of a video link
	 * @see edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#video()
	 */
	@Override
	public void video() {
		MyCompiler.lexer.getNextToken();

		if(!LexicalTokens.textList.contains(MyCompiler.token)){
			System.err.println("Syntax Error: Not valid text, tag found");
			System.exit(0);
		}
		
		MyCompiler.lexer.getNextToken();
		if (!MyCompiler.token.equalsIgnoreCase(LexicalTokens.VIDEO_END)){
			System.err.println("Syntax Error: "+ MyCompiler.token +" when " + LexicalTokens.COMMENT_END +" was expected.");
			System.exit(0);
		}
	}

	/**
	 *Method that checks for remaining syntax of defining a variable
	 * @see edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#define()
	 */
	@Override
	public void define() {
		MyCompiler.lexer.getNextToken();

		if(!LexicalTokens.textList.contains(MyCompiler.token)){
			System.err.println("Syntax Error: Not valid text, tag found");
			System.exit(0);
		}
		
		MyCompiler.lexer.getNextToken();
		
		if (!MyCompiler.token.equalsIgnoreCase(LexicalTokens.DEFINE_VARI_MIDDLE)){
			System.err.println("Syntax Error: "+ MyCompiler.token +" when " + LexicalTokens.DEFINE_VARI_MIDDLE +" was expected.");
			System.exit(0);
		}
		MyCompiler.lexer.getNextToken();

		if(!LexicalTokens.textList.contains(MyCompiler.token)){
				System.err.println("Syntax Error: Not valid text, tag found");
				System.exit(0);
			}
		
		MyCompiler.lexer.getNextToken();

		if (!MyCompiler.token.equalsIgnoreCase(LexicalTokens.DEFINE_VAR_END)){
			System.err.println("Syntax Error: "+ MyCompiler.token + " when " + LexicalTokens.DEFINE_VAR_END +" was expected.");
			System.exit(0);
		}
		MyCompiler.lexer.getNextToken();
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.DEFINE_VAR_BEGIN)){
			define();
		}
	}

	/**
	 *Method that checks for remaining syntax using a variable definition
	 * @see edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#use()
	 */
	@Override
	public void use() {
		MyCompiler.lexer.getNextToken();
		if(!LexicalTokens.textList.contains(MyCompiler.token)){
			System.err.println("Syntax Error: Not valid text, tag found");
			System.exit(0);
			}
		MyCompiler.lexer.getNextToken();
		if (!MyCompiler.token.equalsIgnoreCase(LexicalTokens.VARIABLE_END)){
			System.err.println("Syntax Error: "+ MyCompiler.token +" when " + LexicalTokens.COMMENT_END +" was expected.");
			System.exit(0);
		}	
	}
}